package cn.parus.dynamicRouter.Filter;

import cn.parus.auth.POJO.DTO.OpaInput;
import io.jsonwebtoken.Claims;
import cn.parus.auth.service.OpaClientService;
import cn.parus.dynamicRouter.utils.JwtUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Map;

/**
 * @Author: Axel
 * @Description: TODO 在路由转发时，解析token内容，并且向OPA服务请求，并且判断是否有权限
 **/
@Slf4j
@Component
public class DynamicRouteFilter implements GlobalFilter, Ordered {

    @Autowired
    JwtUtils jwtUtils;
    @Autowired
    OpaClientService opaClientService;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        String token = exchange.getRequest().getHeaders().getFirst("Authorization");
        log.info("token:{}", token);
        if (token != null) {
            // 移除 Bearer 前缀，只保留 token
            /**
             * TODO 首先校验token是否正常
             */
            if (jwtUtils.isNotExpired(token)) {
                /**
                 * TODO 解析token
                 */
                Map<String, Object> claimsMap = jwtUtils.parseJWT(token);
                /**
                 * TODO 向OPA服务发送请求，验证权限是否允许访问
                 */
                OpaInput opaInput = new OpaInput(claimsMap);
                if(opaClientService.querryForDocument(opaInput).getAllow() == true) {
                    // 继续执行过滤链
                    return chain.filter(exchange);
                }
            } else {
                // Token 已过期，处理相应逻辑，例如返回 401 错误或其他处理
                // 例如，直接返回响应，表示未认证
                exchange.getResponse().setStatusCode(HttpStatus.UNAUTHORIZED);
                return exchange.getResponse().setComplete();
            }
        }
        // 如果路由转发时没有携带Token则错误返回
        exchange.getResponse().setStatusCode(HttpStatus.BAD_REQUEST);
        return exchange.getResponse().setComplete();
    }

    /**
     * 过滤器优先级
     * @return
     */
    @Override
    public int getOrder() {
        return -1;
    }
}
